﻿using PC.AzureMultiApp.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using PC.AzureMultiApp.Core.Models;
using PC.AzureMultiApp.Core.Moles;
using PC.AzureMultiApp.Storage.Moles;
using PC.AzureMultiApp.Storage;
using System.Collections.Generic;
using PC.AzureMultiApp.Core.Helpers.Moles;
using System.IO;

namespace Core.Test
{
    
    
    /// <summary>
    ///This is a test class for DeploymentManagerTest and is intended
    ///to contain all DeploymentManagerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class DeploymentManagerTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod()]
        [DeploymentItem("PC.AzureMultiApp.Core.dll")]
        [HostType("Moles")]
        public void CreateApplication_NoWebDeploy_Test()
        {
            ApplicationModel app = new ApplicationModel();
            app.IsWebDeploy = false;
            app.UniqueId = Guid.NewGuid().ToString();

            string zipFile = string.Empty; 
            bool doBackup = false; 
            bool expected = true; 
            bool actual;

            string basePath = Path.Combine(testContextInstance.DeploymentDirectory, "CreateApplicationTest");
            MFileHelper.GetBaseDirectory = () =>
                {
                    return basePath;
                };

            MFileHelper.UnzipStringStringBoolean = (a,b,c) =>
            {
                return true;
            };

            bool before = false;
            MCommands.LaunchBeforeCmdIfExistsString = (string path) => { before = true;  return true; };

            bool afterWait = false;
            MCommands.LaunchAfterAndNoWaitCmdIfExistsString = (string path) => { afterWait = true; return true; };

            bool after = false;
            MCommands.LaunchAfterAndWaitCmdIfExistsString = (string path) => { after = true; return true; };

            actual = DeploymentManager_Accessor.CreateApplication(app, zipFile, doBackup);
            Assert.AreEqual(expected, actual);
            Assert.IsTrue(before);
            Assert.IsTrue(afterWait);
            Assert.IsTrue(after);
        }

        [TestMethod()]
        [DeploymentItem("PC.AzureMultiApp.Core.dll")]
        [HostType("Moles")]
        [Ignore] // Mock ServerManager
        public void CreateApplication_WebDeploy_Test()
        {
            ApplicationModel app = new ApplicationModel();
            app.IsWebDeploy = false;
            app.UniqueId = Guid.NewGuid().ToString();

            string zipFile = string.Empty;
            bool doBackup = false;
            bool expected = true;
            bool actual;

            string basePath = Path.Combine(testContextInstance.DeploymentDirectory, "CreateApplicationTest");
            MFileHelper.GetBaseDirectory = () =>
            {
                return basePath;
            };

            MFileHelper.UnzipStringStringBoolean = (a, b, c) =>
            {
                return true;
            };

            bool before = false;
            MCommands.LaunchBeforeCmdIfExistsString = (string path) => { before = true; return true; };

            bool afterWait = false;
            MCommands.LaunchAfterAndNoWaitCmdIfExistsString = (string path) => { afterWait = true; return true; };

            bool after = false;
            MCommands.LaunchAfterAndWaitCmdIfExistsString = (string path) => { after = true; return true; };

            actual = DeploymentManager_Accessor.CreateApplication(app, zipFile, doBackup);
            Assert.AreEqual(expected, actual);
            Assert.IsTrue(before);
            Assert.IsTrue(afterWait);
            Assert.IsTrue(after);
        }

        [TestMethod()]
        [DeploymentItem("PC.AzureMultiApp.Core.dll")]
        [HostType("Moles")]
        public void CreateApplication_LaunchBeforeError_Test()
        {
            ApplicationModel app = new ApplicationModel();
            app.IsWebDeploy = false;
            app.UniqueId = Guid.NewGuid().ToString();

            string zipFile = string.Empty;
            bool doBackup = false;
            bool expected = false;
            bool actual;

            string basePath = Path.Combine(testContextInstance.DeploymentDirectory, "CreateApplicationTest");
            MFileHelper.GetBaseDirectory = () =>
            {
                return basePath;
            };

            MFileHelper.UnzipStringStringBoolean = (a, b, c) =>
            {
                return true;
            };

            bool before = false;
            MCommands.LaunchBeforeCmdIfExistsString = (string path) => { before = true; return false; };

            bool afterWait = false;
            MCommands.LaunchAfterAndNoWaitCmdIfExistsString = (string path) => { afterWait = true; return true; };

            bool after = false;
            MCommands.LaunchAfterAndWaitCmdIfExistsString = (string path) => { after = true; return true; };

            actual = DeploymentManager_Accessor.CreateApplication(app, zipFile, doBackup);
            Assert.AreEqual(expected, actual);
            Assert.IsTrue(before);
            Assert.IsFalse(afterWait);
            Assert.IsFalse(after);
        }

        [TestMethod()]
        [DeploymentItem("PC.AzureMultiApp.Core.dll")]
        [HostType("Moles")]
        public void CreateApplication_UnZipError_Test()
        {
            ApplicationModel app = new ApplicationModel();
            app.IsWebDeploy = false;
            app.UniqueId = Guid.NewGuid().ToString();

            string zipFile = string.Empty;
            bool doBackup = false;
            bool expected = false;
            bool actual;

            string basePath = Path.Combine(testContextInstance.DeploymentDirectory, "CreateApplicationTest");
            MFileHelper.GetBaseDirectory = () =>
            {
                return basePath;
            };

            MFileHelper.UnzipStringStringBoolean = (a, b, c) =>
            {
                return false;
            };

            bool before = false;
            MCommands.LaunchBeforeCmdIfExistsString = (string path) => { before = true; return true; };

            bool afterWait = false;
            MCommands.LaunchAfterAndNoWaitCmdIfExistsString = (string path) => { afterWait = true; return true; };

            bool after = false;
            MCommands.LaunchAfterAndWaitCmdIfExistsString = (string path) => { after = true; return true; };

            actual = DeploymentManager_Accessor.CreateApplication(app, zipFile, doBackup);
            Assert.AreEqual(expected, actual);
            Assert.IsTrue(before);
            Assert.IsFalse(afterWait);
            Assert.IsFalse(after);
        }


        [TestMethod()]
        [DeploymentItem("PC.AzureMultiApp.Core.dll")]
        [HostType("Moles")]
        public void DeleteApplication_NoWebDeploy_Test()
        {
            string uniqueId = "uniqueId";
            string applicationName = "uniqueId";
            bool isWebDeploy = false;

            string basePath = Path.Combine(testContextInstance.DeploymentDirectory, "DeleteApplicationTest");
            if (!Directory.Exists(basePath))
                Directory.CreateDirectory(basePath);

            string appPath = Path.Combine(basePath, uniqueId);
            if (!Directory.Exists(appPath))
                Directory.CreateDirectory(appPath);

            MFileHelper.GetBaseDirectory = () =>
            {
                return basePath;
            };

            bool uninstall = false;
            MCommands.LaunchUnistallCmdIfExistsString = (string path) => { uninstall = true; return true; };

            DeploymentManager_Accessor.DeleteApplication(uniqueId, applicationName, isWebDeploy);

            Assert.IsFalse(Directory.Exists(appPath));
            Assert.IsTrue(uninstall);
            
        }

        [TestMethod()]
        [DeploymentItem("PC.AzureMultiApp.Core.dll")]
        [HostType("Moles")]
        [Ignore]
        public void DeleteApplication_WebDeploy_Test()
        {
            string uniqueId = "uniqueId";
            string applicationName = "uniqueId";
            bool isWebDeploy = true;

            string basePath = Path.Combine(testContextInstance.DeploymentDirectory, "DeleteApplicationTest");
            if (!Directory.Exists(basePath))
                Directory.CreateDirectory(basePath);

            string appPath = Path.Combine(basePath, uniqueId);
            if (!Directory.Exists(appPath))
                Directory.CreateDirectory(appPath);

            MFileHelper.GetBaseDirectory = () =>
            {
                return basePath;
            };

            bool uninstall = false;
            MCommands.LaunchUnistallCmdIfExistsString = (string path) => { uninstall = true; return true; };

            DeploymentManager_Accessor.DeleteApplication(uniqueId, applicationName, isWebDeploy);

            Assert.IsFalse(Directory.Exists(appPath));
            Assert.IsTrue(uninstall);

        }


        [TestMethod()]
        [HostType("Moles")]
        public void DeleteDeploymentTest()
        {
            string uniqueId = "uniqueId"; 
            string applicationName = "applicationName";

            PC.AzureMultiApp.Core.Moles.MDeploymentManager.DeleteApplicationStringStringBoolean = (a, b, c) =>
                {
                    Assert.AreEqual(a, uniqueId);
                    Assert.AreEqual(b, applicationName);
                };

            DeploymentManager.DeleteDeployment(uniqueId, applicationName, false);
            
        }

        [TestMethod()]
        public void DeleteDeployment_EmptyParams_Test()
        {
            string uniqueId = string.Empty;
            string applicationName = string.Empty;
            DeploymentManager.DeleteDeployment(uniqueId, applicationName, false);
        }

        [TestMethod()]
        [HostType("Moles")]
        public void DeployTest()
        {
            MDeploymentManager.DeployApplicationModelBoolean = (a, b) => { };

            MApplicationDataSource.Constructor = (a)
                => { };

            MApplicationDataSource.AllInstances.GetAll = (datasource)
                =>
            {
                return new List<AzureApplicationEntity>() { new AzureApplicationEntity() };
            };

            DeploymentManager.Deploy();
            
        }

        [TestMethod()]
        [HostType("Moles")]
        public void DeployNoDeploymentsTest()
        {
            MDeploymentManager.DeployApplicationModelBoolean = (a, b) => { };

            MApplicationDataSource.Constructor = (a)
                => { };

            MApplicationDataSource.AllInstances.GetAll = (datasource)
                =>
            {
                return new List<AzureApplicationEntity>();
            };

            DeploymentManager.Deploy();

        }


    }
}
